#pragma once
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../common/util.hpp"
#include "../common/Log.hpp"
using namespace std;

// 只负责进行代码的编译
class Compiler
{
public:
    Compiler()
    {}
    ~Compiler()
    {}
    static bool Compile(const string &file_name)
    {
        pid_t pid = fork();
        if(pid < 0)
        {
            lg(LOG_ERROR_CODE, "内部错误，创建子进程失败");
            return false;
        }
        else if (pid == 0)
        {
            umask(0);
            int _stderr = open(PathUtil::CompilerError(file_name).c_str(), O_CREAT | O_WRONLY, 0644);
            if(_stderr < 0)
            {
                lg(Warning, "没有生成stderr文件");
                exit(1);
            }
            dup2(_stderr, 2);
            //g++ -o target src -std=c++11
            execlp("g++", "g++", "-o", PathUtil::Exe(file_name).c_str(),\
            PathUtil::Src(file_name).c_str(), "-D", "COMPILER_ONLINE","-std=c++11",  nullptr);
            lg(LOG_ERROR_CODE, "启动编译器失败");
            exit(2);
        }
        else
        {
            waitpid(pid, nullptr, 0);
            // 编译是否成功,就看有没有形成对应的可执行程序
            if(FileUtil::IsFileExists(PathUtil::Exe(file_name)))
            {
                lg(Info, "%s：编译成功", PathUtil::Src(file_name).c_str());
                return true;
            }
        }
        lg(LOG_ERROR_CODE, "编译失败");
        return false;
    }
};
